# SPDX-FileCopyrightText: 2021-2025 Nicotine+ Contributors
# SPDX-License-Identifier: GPL-3.0-or-later

import os
import shutil

from unittest import TestCase

from pynicotine.config import config
from pynicotine.core import core
from pynicotine.transfers import TransferStatus

CURRENT_FOLDER_PATH = os.path.dirname(os.path.realpath(__file__))
DATA_FOLDER_PATH = os.path.join(CURRENT_FOLDER_PATH, "temp_data")
TRANSFERS_BASENAME = "uploads.json"
TRANSFERS_FILE_PATH = os.path.join(CURRENT_FOLDER_PATH, TRANSFERS_BASENAME)
SAVED_TRANSFERS_FILE_PATH = os.path.join(DATA_FOLDER_PATH, TRANSFERS_BASENAME)


class UploadsTest(TestCase):

    # pylint: disable=protected-access

    def setUp(self):

        config.set_data_folder(DATA_FOLDER_PATH)
        config.set_config_file(os.path.join(DATA_FOLDER_PATH, "temp_config"))

        if not os.path.exists(DATA_FOLDER_PATH):
            os.makedirs(DATA_FOLDER_PATH)

        shutil.copy(TRANSFERS_FILE_PATH, os.path.join(DATA_FOLDER_PATH, TRANSFERS_BASENAME))

        core.init_components(enabled_components={"users", "shares", "uploads", "buddies"})
        core.start()

    def tearDown(self):
        core.quit()

    @classmethod
    def tearDownClass(cls):
        shutil.rmtree(DATA_FOLDER_PATH)

    def test_load_uploads(self):
        """Test loading a uploads.json file."""

        transfers = list(core.uploads.transfers.values())

        # Only finished uploads are loaded, other types should never be stored
        self.assertEqual(len(transfers), 3)

        transfer = transfers[2]

        self.assertEqual(transfer.username, "user5")
        self.assertEqual(transfer.virtual_path, "Junk\\Song5.mp3")
        self.assertEqual(transfer.status, TransferStatus.FINISHED)
        self.assertEqual(transfer.size, 11733776)
        self.assertEqual(transfer.current_byte_offset, 11733776)
        self.assertIsNone(transfer.file_attributes.bitrate)
        self.assertIsNone(transfer.file_attributes.length)
        self.assertIsNone(transfer.file_attributes.vbr)
        self.assertIsNone(transfer.file_attributes.sample_rate)
        self.assertIsNone(transfer.file_attributes.bit_depth)

        transfer = transfers[0]

        self.assertEqual(transfer.username, "user3")
        self.assertEqual(transfer.virtual_path, "Junk\\Song3.flac")
        self.assertEqual(transfer.status, TransferStatus.FINISHED)
        self.assertEqual(transfer.size, 27231044)
        self.assertEqual(transfer.current_byte_offset, 27231044)
        self.assertEqual(transfer.file_attributes.bitrate, 792)
        self.assertEqual(transfer.file_attributes.length, 268)
        self.assertIsNone(transfer.file_attributes.vbr)
        self.assertIsNone(transfer.file_attributes.sample_rate)
        self.assertIsNone(transfer.file_attributes.bit_depth)

    def test_save_uploads(self):
        """Verify that the order of the upload list at the end of the session
        is identical to the one we loaded.

        Ignore the first two unfinished uploads, since only finished uploads are
        saved to file.
        """

        old_transfers = core.uploads._load_transfers_file(TRANSFERS_FILE_PATH)[2:]
        core.uploads._save_transfers()
        saved_transfers = core.uploads._load_transfers_file(SAVED_TRANSFERS_FILE_PATH)

        self.assertEqual(old_transfers, saved_transfers)

    def test_push_upload(self):
        """Verify that non-existent files are not added to the list."""

        core.uploads.enqueue_upload("newuser2", "Hello\\Upload\\File.mp3")
        core.uploads.enqueue_upload("newuser99", "Home\\None.mp3")

        self.assertEqual(len(core.uploads.transfers.values()), 3)
